﻿Imports System.Windows.Forms

Public Class SelectTZ
    Dim _city As String
    Dim _state As String
    Dim _country As String
    Dim _dtAvailableTimeZones As System.Data.DataTable
    Dim _result As String = ""
    Shared _oApp As Outlook.Application

    Overloads Function ShowDialog(ByRef dtAvailableTimeZones As System.Data.DataTable, _
        ByVal city As String, ByVal state As String, ByVal country As String, _
         ByRef oApp As Outlook.Application) As String
        LogToStatusLog("Lookign up:" & city & "," & state & "," & country)
        _city = city
        _state = state
        _country = country
        _oApp = oApp
        _dtAvailableTimeZones = dtAvailableTimeZones
        Timer1.Enabled = True
        Timer1.Interval = 5
        Me.Text = "Getting Time Zones"
        Me.Cursor = Cursors.WaitCursor
        Me.lbTimeZones.Items.Add("Please wait... filtering time zones")
        Me.Refresh()
        Me.ShowDialog()
        ShowDialog = _result
    End Function

    Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.OK
        _result = GetSelection()
        Me.Close()
    End Sub

    Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
        Me.Close()
    End Sub
    Function LookupTZIDFromDisplayTZ(ByVal displayTZ As String) As String
        Dim dr As System.Data.DataRow
        Dim result As String = ""

        For Each dr In _dtAvailableTimeZones.Rows
            If Not dr.IsNull("DisplayName") Then
                If dr.Item("DisplayName") = displayTZ Then
                    result = dr.Item("ValueName").ToString
                    Exit For
                End If
            End If
        Next
        LookupTZIDFromDisplayTZ = result
    End Function
    Function GetSelection() As String
        Dim s As String
        s = lbTimeZones.SelectedItem
        GetSelection = ""
        If s <> "" Then
            Dim dr As System.Data.DataRow

            For Each dr In _dtAvailableTimeZones.Rows
                If dr.Item("DisplayName") = s Then
                    GetSelection = dr.Item("ValueName")
                    Exit For
                End If
            Next
        Else
            GetSelection = LookupTZIDFromDisplayTZ(cbTimeZones.SelectedItem)
        End If
    End Function

    Sub PopulateListBox(ByVal offset As String)
        Dim dr As System.Data.DataRow

        For Each dr In _dtAvailableTimeZones.Rows
            If Decimal.Parse(dr.Item("offset").ToString) = Decimal.Parse(offset) Then
                Me.lbTimeZones.Items.Add(dr.Item("DisplayName"))
            End If
            Me.cbTimeZones.Items.Add(dr.Item("DisplayName"))
        Next
    End Sub
    Function GoogleGetLatLong(ByVal city As String, ByVal state As String, ByVal country As String) As String
        Dim xmlDoc As New System.Xml.XmlDocument
        Dim search As String
        GoogleGetLatLong = ""
        Try
            ' the key value comes from registering with google for using their api.
            search = String.Format("http://maps.google.com/maps/geo?q={0}&output=xml&key={1}", _
                                   city & "," & state & "," & country, _
                                   "ABQIAAAAksDVe3zlXQz5hp4aV5dhfhST54WnbCzeLinNIdmTlBBnkPktHxQnYW4uYrkx74YvJOnUOkdabZtoog")
            LogToStatusLog(search)

            Dim req As System.Net.WebRequest
            Dim resp As System.Net.WebResponse

            req = System.Net.WebRequest.Create(search)
            req.Proxy = System.Net.WebRequest.DefaultWebProxy ' New System.Net.WebProxy("localhost:8080", True)
            req.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials
            req.Timeout = My.Settings.webServiceTimeOut * 1000
            resp = req.GetResponse()

            Dim textReader As System.IO.StreamReader
            Dim xmlReader As System.Xml.XmlTextReader

            textReader = New System.IO.StreamReader(resp.GetResponseStream())
            xmlReader = New System.Xml.XmlTextReader(textReader)
            xmlDoc.Load(xmlReader)
            'This is where I learned about using xmlnamespacemanager http://tlaughlin.pandorasystems.com/blogs/tlaughlin/archive/2006/12/09/xpath-with-namespace-in-vb-net.aspx

            Dim ObjNode As System.Xml.XmlNode
            Dim ObjMgr As System.Xml.XmlNamespaceManager

            ObjMgr = New System.Xml.XmlNamespaceManager(xmlDoc.NameTable)
            ObjMgr.AddNamespace("a", "http://earth.google.com/kml/2.0")
            LogToStatusLog(xmlDoc.InnerXml)
            Try
                ObjNode = xmlDoc.SelectSingleNode("//a:coordinates", ObjMgr)
                GoogleGetLatLong = ObjNode.InnerXml
                LogToStatusLog(ObjNode.InnerXml)
            Catch ex As Exception
                LogToStatusLog(ex.Message)
            End Try

        Catch ex As Exception
            LogToStatusLog(ex.Message & vbCrLf & ex.StackTrace)
        End Try

    End Function

    Function GetTimeZoneFromLatLong(ByVal lat As Decimal, ByVal lon As Decimal) As String
        Dim xmlDoc As New System.Xml.XmlDocument
        Dim TZWebServices() As String = {"http://www.earthtools.org/timezone/{0}/{1}", "http://ws.geonames.org/timezone?lat={0}&lng={1}"}
        Dim TZResultPath() As String = {"//timezone/offset", "//geonames/timezone/gmtOffset"}
        Dim webService As String
        Dim i As Integer
        Dim req As System.Net.WebRequest
        Dim resp As System.Net.WebResponse
        GetTimeZoneFromLatLong = ""
        Dim dr As System.Data.DataRow
        Try
            For Each dr In ThisAddIn.dsWebServices.Tables("TZWebService").Rows
                'For i = 0 To UBound(TZWebServices)
                'webService = String.Format(TZWebServices(i), lat, lon)
                webService = String.Format(dr.Item("WebServiceFormatString"), lat, lon)
                LogToStatusLog(webService)
                req = System.Net.WebRequest.Create(webService)
                req.Proxy = System.Net.WebRequest.DefaultWebProxy
                req.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials
                req.Timeout = My.Settings.webServiceTimeOut * 1000

                Try
                    resp = req.GetResponse()
                    Dim textReader As System.IO.StreamReader
                    Dim xmlReader As System.Xml.XmlTextReader

                    textReader = New System.IO.StreamReader(resp.GetResponseStream())
                    xmlReader = New System.Xml.XmlTextReader(textReader)
                    xmlDoc.Load(xmlReader)

                    Try
                        GetTimeZoneFromLatLong = xmlDoc.SelectSingleNode(TZResultPath(i)).InnerXml
                        LogToStatusLog(xmlDoc.InnerXml)
                        LogToStatusLog("TZ:" & GetTimeZoneFromLatLong.ToString)
                        Exit For
                    Catch ex As Exception
                        LogToStatusLog(ex.Message & vbCrLf & ex.StackTrace)
                    End Try
                Catch ex As Exception
                    LogToStatusLog(ex.Message)
                    If i < UBound(TZWebServices) Then
                        LogToStatusLog("Trying next time zone webservice.")
                    End If
                End Try

            Next
        Catch ex As Exception
            LogToStatusLog(ex.Message & vbCrLf & ex.StackTrace)
        End Try
    End Function

    Private Sub cbTimeZones_SelectedValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbTimeZones.SelectedValueChanged
        lbTimeZones.ClearSelected()
    End Sub
    Sub LogToStatusLog(ByVal message As String)
        statusBox.Text = statusBox.Text & Now.ToLongTimeString & " : " & message & vbCrLf

    End Sub
    Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Try

        Dim s() As String
            Dim ss As String
            Timer1.Enabled = False
            Me.Refresh()
            LogToStatusLog("Get Lat Long")
            s = Split(GoogleGetLatLong(_city, _state, _country), ",")
            If UBound(s) > 1 Then
                LogToStatusLog("Get Time Zone")
                ss = GetTimeZoneFromLatLong(s(1), s(0))
                Me.lbTimeZones.Items.Clear()
                If ss <> "" Then
                    PopulateListBox(ss)
                Else
                    Me.lbTimeZones.Items.Clear()
                    Me.lbTimeZones.Items.Add("Problem gettnig timezone from lat/long of location.")
                    Me.lbTimeZones.Items.Add("Select time zone from drop down list below.")

                End If
            Else
                Me.lbTimeZones.Items.Clear()
                Me.lbTimeZones.Items.Add("Location could not be found.")
                Me.lbTimeZones.Items.Add("Select time zone from drop down list below.")
                PopulateListBox(99)
            End If
            Me.Cursor = Cursors.Default
            Me.Text = _city & ", " & _state & ", " & _country
        Catch ex As Exception
            ShowError(ex.Message, ex.StackTrace)
        End Try


    End Sub
    Shared Sub ShowError(ByVal condition As String, ByVal stackTrace As String)
        Dim se As New ErrorDialog


        If se.Show(condition, stackTrace) = System.Windows.Forms.DialogResult.Yes Then
            Dim m As Outlook.MailItem
            m = _oApp.CreateItem(Outlook.OlItemType.olMailItem)
            m.To = "brady@acm.org"
            m.Subject = "Outlook 2007 DIT Error Report"
            m.Body = My.Resources.reportErrorPreamble & vbCrLf & condition & vbCrLf & stackTrace
            m.Display(True)
        End If
    End Sub

    Private Sub SelectTZ_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        statusBox.Visible = showLog.Checked
        If showLog.Checked = True Then
            Me.Height = statusBox.Location.Y + statusBox.Height + 75
        Else
            Me.Height = cbTimeZones.Location.Y + cbTimeZones.Height + 75
        End If

    End Sub

    Private Sub showLog_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles showLog.Click
        statusBox.Visible = showLog.Checked
        If showLog.Checked = True Then
            Me.Height = statusBox.Location.Y + statusBox.Height + 75
        Else
            Me.Height = cbTimeZones.Location.Y + cbTimeZones.Height + 75
        End If

    End Sub
End Class
